﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace YoUI.Core
{
    /// <summary>
    /// UI管理器
    /// </summary>
    public class Yo
    {
        // 单例
        private static Yo _Yo;

        public static Yo _
        {
            get
            {
                if (_Yo == null)
                {
                    _Yo = new Yo();
                    _Yo.Init();
                }
                return _Yo;
            }
        }

        // 窗口预制体 路径
        private Dictionary<string, string> _DicUIPath;

        // 缓存加载后的UI
        private Dictionary<string, YoBase> _DicCacheUI;

        // 所有显示的UI
        private Dictionary<string, YoBase> _DicShowUI;

        // 栈管理窗口显示
        private Stack<YoBase> _StackShowUI;

        // 单一最前窗口
        private YoBase _SingleTopUI;

        // 跟节点
        public Transform _Canvas;

        private Transform _Normal;

        private Transform _Fixed;

        private Transform _PopUp;

        // 初始化
        private Yo()
        {
            _DicUIPath = new Dictionary<string, string>();
            _DicCacheUI = new Dictionary<string, YoBase>();
            _DicShowUI = new Dictionary<string, YoBase>();
            _StackShowUI = new Stack<YoBase>();

            // 加载UI画布
            GameObject canvas = Resources.Load<GameObject>(YoSysDefine.Yo_ROOT + "/" + "_UICanvas");
            _Canvas = Object.Instantiate(canvas).GetComponent<Transform>();

            // 切换场景时不销毁
            Object.DontDestroyOnLoad(_Canvas);

            // 寻找窗口挂载点
            _Normal = _Canvas.Find("_Normal");
            _Fixed = _Canvas.Find("_Fixed");
            _PopUp = _Canvas.Find("_PopUp");

            if (_Canvas != null && _Normal != null && _Fixed != null && _PopUp != null)
                Debug.Log("CUI:UIMananger->初始化成功！");
            else
                Debug.Log("CUI:UIMananger->初始化失败！");
        }

        /// <summary>
        /// 显示一个UI窗口
        /// </summary>
        /// <param name="name">UI窗口名称</param>
        public void Show(string name)
        {

            if (string.IsNullOrEmpty(name))
                return;

            YoBase ui = LoadUI(name);

            if (ui == null)
                return;

            switch (ui._UIFormShowMode)
            {
                case YoSysDefine.UIFormShowMode.Normal:
                    EnterNormal(name);
                    break;
                case YoSysDefine.UIFormShowMode.Reverse:
                    PushUI(name);
                    break;
                case YoSysDefine.UIFormShowMode.HideOther:
                    EnterHideOther(name);
                    break;
                case YoSysDefine.UIFormShowMode.SingleTop:
                    EnterSingleTop(name);
                    break;
            }

        }

        /// <summary>
        /// 关闭窗口
        /// </summary>
        /// <param name="name"></param>
        public void Close(string name)
        {
            if (string.IsNullOrEmpty(name))
                return;

            YoBase ui = null;
            if (!_DicCacheUI.TryGetValue(name, out ui))
                return;

            switch (ui._UIFormShowMode)
            {
                case YoSysDefine.UIFormShowMode.Normal:
                    ExitNormal(name);
                    break;
                case YoSysDefine.UIFormShowMode.Reverse:
                    PopUI(name);
                    break;
                case YoSysDefine.UIFormShowMode.HideOther:
                    ExitHideOther(name);
                    break;
                case YoSysDefine.UIFormShowMode.SingleTop:
                    ExitSingleTop();
                    break;
            }
        }

        /// <summary>
        /// 加载UI
        /// </summary>
        /// <param name="name">UI名称</param>
        public YoBase LoadUI(string name)
        {
            YoBase ui = null;
            // 缓存中存在这个UI
            if (_DicCacheUI.TryGetValue(name, out ui))
            {
                return ui;
            }

            // 不存在
            return LoadAndAttachUI(name);
        }

        /// <summary>
        /// 加载和挂载UI
        /// </summary>
        /// <param name="name">名称</param>
        /// <returns></returns>
        public YoBase LoadAndAttachUI(string name)
        {
            // 缓存中不存在这个UI，从资源路径中，进行加载。
            string loadPath = "";
            if (!_DicUIPath.TryGetValue(name, out loadPath))
            {
                return null;

            }

            var prefab = Resources.Load<GameObject>(YoSysDefine.Yo_ROOT + "/" + loadPath);
            var uiObj = Object.Instantiate(prefab);

            YoBase ui = uiObj.GetComponent<YoBase>();

            if (ui == null)
            {
                Debug.Log("加载UI失败，请确认[ " + name + " ]这个UI上是否挂载了，UI脚本。");
                return null;
            }

            // 根据UI类型 进行挂载
            switch (ui._UIFormType)
            {
                case YoSysDefine.UIFormType.Normal:
                    uiObj.transform.SetParent(_Normal, false);
                    break;
                case YoSysDefine.UIFormType.Fixed:
                    uiObj.transform.SetParent(_Fixed, false);
                    break;
                case YoSysDefine.UIFormType.PopUp:
                    uiObj.transform.SetParent(_PopUp, false);
                    break;
            }

            uiObj.SetActive(false);
            _DicCacheUI.Add(name, ui);
            return ui;
        }

        /// <summary>
        /// 显示默认窗口
        /// </summary>
        /// <param name="ui"></param>
        public void EnterNormal(string name)
        {
            // 正在显示集合是否已存在
            YoBase ui = null;
            if (_DicShowUI.TryGetValue(name, out ui))
            {
                return;
            }

            if (_DicCacheUI.TryGetValue(name, out ui))
            {
                _DicShowUI.Add(name, ui);
                ui.Show();
            }
        }

        /// <summary>
        /// 关闭默认窗口
        /// </summary>
        /// <param name="name"></param>
        public void ExitNormal(string name)
        {
            YoBase ui = null;

            if (_DicShowUI.TryGetValue(name, out ui))
            {
                ui.Hide();
                _DicShowUI.Remove(name);
            }
        }


        /// <summary>
        /// PopUp 窗口进栈
        /// </summary>
        /// <param name="name"></param>
        public void PushUI(string name)
        {
            YoBase ui = _DicCacheUI[name];

            if (_StackShowUI.Count > 0 && _StackShowUI.Peek() == ui)
            {
                return;
            }

            if (_StackShowUI.Count > 0)
            {
                // 冻结栈顶UI窗口
                _StackShowUI.Peek().Freeze();
            }



            if (_DicCacheUI.TryGetValue(name, out ui))
            {
                ui.Show();
                _StackShowUI.Push(ui);
            }
        }

        /// <summary>
        /// 单一最前窗口
        /// </summary>
        public void EnterSingleTop(string name)
        {
            YoBase ui = _DicCacheUI[name];


            if (ui == _SingleTopUI)
                return;

            if (_SingleTopUI != null && ui != _SingleTopUI)
            {
                _SingleTopUI.Hide();
            }
            _SingleTopUI = ui;
            _SingleTopUI.Show();
        }

        /// <summary>
        /// PopUp 窗口出栈
        /// </summary>
        /// <param name="name"></param>
        public void PopUI(string name)
        {
            // 如果窗口有2个以上，就移除栈顶并隐藏。重新显示栈顶UI。
            if (_StackShowUI.Count >= 2)
            {
                _StackShowUI.Pop().Hide();
                _StackShowUI.Peek().ReShow();
            }
            else if (_StackShowUI.Count == 1)
            {
                _StackShowUI.Pop().Hide();
            }
        }

        /// <summary>
        /// 显示自己，隐藏其他所有窗口。
        /// </summary>
        /// <param name="name"></param>
        public void EnterHideOther(string name)
        {
            YoBase ui = null;
            // 正在显示UI集合中，有当前窗口，就自己返回。
            if (_DicShowUI.TryGetValue(name, out ui))
                return;

            foreach (var item in _DicShowUI.Values)
            {
                item.Hide();
            }

            foreach (var item in _StackShowUI)
            {
                item.Hide();
            }

            if (_DicCacheUI.TryGetValue(name, out ui))
            {
                _DicShowUI.Add(name, ui);
                ui.Show();
            }
        }

        /// <summary>
        /// 关闭
        /// </summary>
        /// <param name="name"></param>
        public void ExitHideOther(string name)
        {
            YoBase ui;
            if (!_DicShowUI.TryGetValue(name, out ui))
                return;

            ui.Hide();
            _DicShowUI.Remove(name);

            foreach (var item in _DicShowUI.Values)
            {
                item.ReShow();
            }

            foreach (var item in _StackShowUI)
            {
                item.ReShow();
            }
        }

        /// <summary>
        /// 关闭单一前窗口
        /// </summary>
        public void ExitSingleTop()
        {
            if (_SingleTopUI != null)
            {
                _SingleTopUI.Hide();
                _SingleTopUI = null;
            }
        }

        /// <summary>
        /// 初始化
        /// </summary>
        public void Init()
        {
            // 遮罩窗口
            YoMaskMgr.GetUIMask.UIMaskPanel = _._Canvas.Find(YoSysDefine.Yo_MaskPanel);

            _DicUIPath = YoConfigMgr._._DicUICFG;

            _.Show("Entry");
        }
    }
}
